package cn.com.generaldata.os.controller;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import lombok.Data;

import org.apache.commons.lang3.StringUtils;
import org.jsoup.helper.StringUtil;
import org.nutz.dao.Dao;
import org.nutz.json.Json;
import org.nutz.json.JsonFormat;
import org.nutz.lang.Stopwatch;
import org.nutz.lang.Streams;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.multiaction.MultiActionController;

import cn.com.generaldata.jsme_indicator_system.entity.ReportTypeLimit;
import cn.com.generaldata.jsme_indicator_system.util.Constants;
import cn.com.generaldata.jsme_indicator_system.util.Constants.ReportStyle;
import cn.com.generaldata.os.constant.FilterConstant;
import cn.com.generaldata.os.constant.ReportConstant;
import cn.com.generaldata.os.mvc.ReportServletHandler;
import cn.com.generaldata.os.newpojo.ReportType;
import cn.com.generaldata.os.paging.Filter;
import cn.com.generaldata.os.paging.FilterRule;
import cn.com.generaldata.os.pojo.Industry;
import cn.com.generaldata.os.pojo.User;
import cn.com.generaldata.os.pojo.mvc.Report;
import cn.com.generaldata.os.pojo.mvc.Row;
import cn.com.generaldata.os.report.check.ReportCheckHandler;
import cn.com.generaldata.os.service.common.AutoPushingService;
import cn.com.generaldata.os.service.common.IndustryService;
import cn.com.generaldata.os.service.common.ReportStatService;
import cn.com.generaldata.os.service.common.ReportTemplateService;
import cn.com.generaldata.os.service.common.RoleService;
import cn.com.generaldata.os.service.common.UserService;
import cn.com.generaldata.os.service.intf.ReportServiceInterface;
import cn.com.generaldata.os.vo.IndicatorStatQueryVO;
import cn.com.generaldata.os.vo.ReportStatResult;
import cn.com.generaldata.os.vo.ReportStatVO;
import cn.com.generaldata.os.vo.ReportVO;

import com.google.common.base.Predicate;
import com.google.common.collect.Collections2;
import com.google.common.collect.Lists;
import com.google.common.net.HttpHeaders;

public class ReportController extends MultiActionController {

	private UserService userServiceInterface;

	private ReportServiceInterface reportServiceInterface;

	private AutoPushingService apServiceInterface;

	public void setApServiceInterface(AutoPushingService apServiceInterface) {
		this.apServiceInterface = apServiceInterface;
	}

	private RoleService roleServiceInterface;

	private IndustryService industryServiceInterface;

	private ReportTemplateService reportTemplateService;

	private ReportStatService reportStatService;

	private Dao indicatorSystemDao;

	private boolean timeLimit;

	/**
	 * 创建报表
	 * 
	 * @param request
	 * @param response
	 * @return
	 * @throws ServletException
	 * @throws IOException
	 */
	@SuppressWarnings("unchecked")
	public ModelAndView showCreateReport(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		Map model = new HashMap();
		//是从催报界面进来的，就只让提交
		model.put("bill", request.getParameter("bill"));
		// 取得创建用户ID
		String userId = request.getParameter("reportOperatorId");
		// 取得代填报表用户ID
		String proxyId = request.getParameter("reportProxyId");

		// 获取报表季度
		String quarterDate = "";
		String lasttimeQuarterDate = "第零季度";
		if ("1".equals(request.getParameter("quarterDate"))) {
			quarterDate = "第一季度";
		}
		if ("2".equals(request.getParameter("quarterDate"))) {
			quarterDate = "第二季度";
			lasttimeQuarterDate = "第一季度";
		}
		if ("3".equals(request.getParameter("quarterDate"))) {
			quarterDate = "第三季度";
			lasttimeQuarterDate = "第二季度";
		}
		if ("4".equals(request.getParameter("quarterDate"))) {
			quarterDate = "第四季度";
			lasttimeQuarterDate = "第三季度";
		}
		String reportDate = request.getParameter("reportDate");
		// 获取报表时段时间
		String timeDate = request.getParameter("timeDate");

		// 取得报表类型
		String reportTypeId = request.getParameter("reportTypeId");
		ReportType rType = reportServiceInterface.queryReportTypeById(reportTypeId);
		// 获取报表时段属性
		String timeType = rType.getTypeTime();
		// 获取报表年属性
		String yearType = rType.getTypeYearTime();
		String yearTypeTemp = request.getParameter("yearType");
		if (!StringUtil.isBlank(yearTypeTemp))
			yearType = yearTypeTemp;
		if (!StringUtil.isBlank(reportDate)) {
			String[] split = reportDate.split("-");
			String year = split[0];
			String month = split[1];
			if ("1".equals(timeType)) {
				if ("2".equals(yearType))
					year = String.valueOf(Integer.valueOf(year) - 1);
				else if ("1".equals(yearType)) {
					if (Integer.valueOf(month) <= 6) {
						yearType = "2";
						year = String.valueOf(Integer.valueOf(year) - 1);
					}
				}

			} else if ("2".equals(timeType)) {
				if (Integer.valueOf(month) <= 3) {
					year = String.valueOf(Integer.valueOf(year) - 1);
					quarterDate = "第四季度";
					lasttimeQuarterDate = "第四季度";
				} else if (Integer.valueOf(month) <= 6 && Integer.valueOf(month) > 3) {
					quarterDate = "第一季度";
					lasttimeQuarterDate = "第一季度";
				} else if (Integer.valueOf(month) <= 9 && Integer.valueOf(month) > 6) {
					quarterDate = "第二季度";
					lasttimeQuarterDate = "第二季度";
				} else if (Integer.valueOf(month) <= 12 && Integer.valueOf(month) > 9) {
					quarterDate = "第三季度";
					lasttimeQuarterDate = "第三季度";
				}
			} else if ("0".equals(timeType)) {
				if (Integer.valueOf(month) == 1) {
					year = String.valueOf(Integer.valueOf(year) - 1);
					month = "12";
				} else
					month = String.valueOf(Integer.valueOf(month) - 1);
			}
			if (Integer.valueOf(month) < 9)
				timeDate = year + "/0" + Integer.valueOf(month);
			else
				timeDate = year + "/" + month;
		}
		// 获取当前报表对应的行业名称ID
		//		 request.getParameter("unitIndustryId");
		// 获取报表版本号
		String reportVersion = request.getParameter("reportVersion");
		cn.com.generaldata.os.pojo.mvc.Report lasttimeReport = new cn.com.generaldata.os.pojo.mvc.Report(); // 上次对比的报表
		cn.com.generaldata.os.pojo.mvc.Report report = new cn.com.generaldata.os.pojo.mvc.Report();

		// 报表所属用户和操作用户
		if (userId == null) {
			return new ModelAndView("/error.jsp", null);
		}
		if (reportTypeId == null) {
			return new ModelAndView("/error.jsp", null);
		}
		Integer versionId = rType.getVersionId();
		Filter filter1 = new Filter();
		filter1.addRule(new FilterRule(FilterConstant.EQUAL, "id", versionId));
		cn.com.generaldata.os.newpojo.ReportVersion version = reportServiceInterface.getVersion(filter1, null);
		// 报表所属用户
		User user = userServiceInterface.queryUserById(userId);

		String unitIndustryId = user.getUserUnit().getIndustryId();
		user.setUserCityName(user.getArea().getAreaDesc());
		// 当前时间
		Calendar date = Calendar.getInstance();
		// 正确填报时间
		Calendar dateOK = Calendar.getInstance();
		// 年
		String yearValue = timeDate.substring(0, 4);
		// 月
		String monthValue = timeDate.substring(5, 7);
		// 不能提前上报
		if (date.get(Calendar.YEAR) < Integer.valueOf(yearValue)) {
			return new ModelAndView("/reportovertime.jsp", null);
		}

		// 季度值
		int quarter = 0;
		String parameter = request.getParameter("quarterDate");
		if (parameter != null && !"".equals(parameter)) {
			quarter = Integer.parseInt(parameter);
		}
		Properties properties = new Properties();
		java.io.InputStream inputstream = getClass().getResourceAsStream("/global_conf.properties");
		try {
			properties.load(inputstream);
		} catch (Exception ex) {
			logger.error("加载配置文件出错", ex);
		}
		String limit = properties.getProperty("limit").trim();
		if ("true".equals(limit)) {
			List<ReportTypeLimit> limitList = reportServiceInterface.queryReportLimit(rType.getStatSystem(),
					reportTypeId, rType.getTypeTime(), yearType);
			// 催报信息
			Integer timeBill = apServiceInterface.queryBillByReport(reportTypeId, user.getUserUnit().getId(), timeType,
					yearType, timeDate, quarterDate);
			if (timeBill == null) {
				timeBill = new Integer(0);
			}
			for (ReportTypeLimit reportLimit : limitList) {
				Integer startDay = reportLimit.getStartDay();
				Integer endDay = reportLimit.getEndDay();
				Integer startMonth = reportLimit.getStartMonth();
				Integer endMonth = reportLimit.getEndMonth();
				// 月报(下月1日+延期)
				if ("0".equals(timeType) && timeType.equals(reportLimit.getTypeTime())) {
					dateOK.set(Calendar.YEAR, Integer.valueOf(yearValue));
					dateOK.set(Calendar.MONTH, Integer.valueOf(monthValue));
					dateOK.set(Calendar.DATE, startDay);
					if (date.before(dateOK)) {
						return new ModelAndView("/reportovertime.jsp", null);
					}
					dateOK.set(Calendar.DAY_OF_YEAR, dateOK.get(Calendar.DAY_OF_YEAR) + endDay - startDay + timeBill);
					if (date.after(dateOK)) {
						return new ModelAndView("/reportovertime.jsp", null);
					}
					break;
				}
				// 季报
				else if ("2".equals(timeType) && timeType.equals(reportLimit.getTypeTime())) {
					if (quarter == 1) {
						dateOK.set(Calendar.YEAR, Integer.valueOf(yearValue));
						dateOK.set(Calendar.MONTH, 3);
					} else if (quarter == 2) {
						dateOK.set(Calendar.YEAR, Integer.valueOf(yearValue));
						dateOK.set(Calendar.MONTH, 6);
					} else if (quarter == 3) {
						dateOK.set(Calendar.YEAR, Integer.valueOf(yearValue));
						dateOK.set(Calendar.MONTH, 9);
					} else if (quarter == 4) {
						dateOK.set(Calendar.YEAR, Integer.valueOf(yearValue) + 1);
						dateOK.set(Calendar.MONTH, 0);
					}
					dateOK.set(Calendar.DATE, startDay);
					if (date.before(dateOK)) {
						return new ModelAndView("/reportovertime.jsp", null);
					}
					dateOK.set(Calendar.DAY_OF_YEAR, dateOK.get(Calendar.DAY_OF_YEAR) + endDay - startDay + timeBill);
					if (date.after(dateOK)) {
						return new ModelAndView("/reportovertime.jsp", null);
					}
					break;
				}
				// 年报
				else if ("1".equals(timeType) && timeType.equals(reportLimit.getTypeTime())) {
					// 全年报
					if ("2".equals(yearType) && reportLimit.getTypeYearTime().equals(yearType)) {
						dateOK.set(Calendar.YEAR, Integer.valueOf(yearValue) + 1);
						dateOK.set(Calendar.MONTH, startMonth - 1);
						dateOK.set(Calendar.DATE, startDay);
						if (date.before(dateOK)) {
							return new ModelAndView("/reportovertime.jsp", null);
						}
						dateOK.set(Calendar.MONTH, endMonth - 1);
						dateOK.set(Calendar.DATE, endDay + timeBill);
						if (date.after(dateOK)) {
							return new ModelAndView("/reportovertime.jsp", null);
						}
					}
					// 半年报
					else if ("1".equals(yearType) && reportLimit.getTypeYearTime().equals(yearType)) {
						dateOK.set(Calendar.YEAR, Integer.valueOf(yearValue));
						dateOK.set(Calendar.MONTH, startMonth - 1);
						dateOK.set(Calendar.DATE, startDay);
						if (date.before(dateOK)) {
							return new ModelAndView("/reportovertime.jsp", null);
						}
						dateOK.set(Calendar.MONTH, endMonth - 1);
						dateOK.set(Calendar.DATE, endDay + timeBill);
						if (date.after(dateOK)) {
							return new ModelAndView("/reportovertime.jsp", null);
						}
					}
					continue;
				}
			}
		}

		model.put("user", user);
		model.put("reportType", rType);

		// 判断当前用户的报表与报表时段是否存在，存在不得保存
		boolean reportTimeType = reportServiceInterface.isReportTimeType(user, rType.getId(), timeType, yearType,
				timeDate, quarterDate, reportVersion);
		if (reportTimeType) { // 表示已经存在
			return new ModelAndView("/reportexisterror.jsp", null);
		}
		// 是否汇总
		Integer summarization = rType.getDataSummarization();
		// 报表汇总类别
		Integer dataType = rType.getDataType();
		// 取得指标汇总数据
		Map accounting = new HashMap();
		// 行式报表详情列表
		List<Row> rowsAccounting = new ArrayList<Row>();
		Stopwatch sw = Stopwatch.beginNano();
		// 用汇总
		if (summarization == Constants.YES) {
			// 指标汇总
			if (dataType.intValue() == ReportStyle.CELL.getValue()) {
				accounting = reportServiceInterface.getReportAccounting(user, rType, timeDate, quarter);
			} else {
				rowsAccounting = reportServiceInterface.getRowsAccounting(user, rType, timeDate, quarter);
			}
		}
		sw.stop();
		logger.info("指标汇总耗时：" + sw);

		// 不同制度的指标对应关系
		if (dataType.intValue() == ReportStyle.CELL.getValue()) {
			sw = Stopwatch.beginNano();
			accounting = reportServiceInterface.getReportIndicator(user, rType, version.getStartDate(), quarter,
					accounting);
			sw.stop();
			logger.info("指标关系耗时：" + sw);
		}
		// 获取上期数据,验证指标数据的增长幅度
		sw = Stopwatch.beginNano();
		Map lastTimeIndicatorMap = reportServiceInterface.getLasttimeReportByTimetype(user, rType, timeDate,
				quarterDate);
		sw.stop();
		logger.info("查询指标上期耗时：" + sw);

		// 处理可以获取上期数据的指标
		if (dataType.intValue() == ReportStyle.CELL.getValue()) {
			reportServiceInterface.addLasttimeCellReportToAccount(rType, lastTimeIndicatorMap, accounting);
		} else {
			List<Row> rows = reportServiceInterface.getLasttimeRowReportRow(user, rType, timeDate, lasttimeQuarterDate);
			rowsAccounting = new ArrayList<Row>(rowsAccounting);
			rowsAccounting.addAll(rows);
		}
		// 如果存在代填用户id，则为代填报表
		User proxyUser = null;
		if (proxyId != null) {
			proxyUser = userServiceInterface.queryUserById(proxyId);
			model.put("proxyUser", proxyUser);
		} else {
			proxyUser = user;
		}
		report = ReportServletHandler.generateReportForNew(user, proxyUser, proxyUser, rType, timeType, yearType,
				timeDate, quarterDate, lasttimeReport, reportVersion, unitIndustryId);
		// 获取下级单位和本级涉海部门报表
		// Area area = user.getArea();

		if (dataType.intValue() == ReportStyle.CELL.getValue()) {
			model.put("accounting", Json.toJson(accounting, JsonFormat.compact()));
		} else {
			report.setRows(rowsAccounting);
		}
		model.put("reportTemplate", reportTemplateService.renderCreateTemplate(reportTypeId, report, user));
		model.put("report", report);
		model.put("lastTimeIndicatorMap", Json.toJson(lastTimeIndicatorMap, JsonFormat.compact()));

		return new ModelAndView("/report-input.jsp", model);
	}

	/**
	 * 重新报表汇总数据
	 * 
	 * @param request
	 * @param response
	 * @return
	 * @throws ServletException
	 * @throws IOException
	 */
	@SuppressWarnings("unchecked")
	public ModelAndView reloadReportAccounting(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		Map model = new HashMap();

		// 获取报表时段时间
		// String timeDate = request.getParameter("reportMonth");

		// 取得操作用户ID
		String userId = request.getParameter("reportOperatorId");
		// 取得报表ID
		String reportId = request.getParameter("reportId");

		// user
		User user = new User();
		cn.com.generaldata.os.pojo.mvc.Report report = new cn.com.generaldata.os.pojo.mvc.Report();

		// Error Flag
		if (userId == null) {
			return new ModelAndView("/error.jsp", null);
		}
		if (reportId == null) {
			return new ModelAndView("/error.jsp", null);
		}
		user = userServiceInterface.queryUserById(userId);
		report = reportServiceInterface.queryMVCReportById(reportId);
		report = ReportServletHandler.generateReportForUpdate(report, user);

		String reportTypeId = report.getReportTypeId();
		ReportType rType = reportServiceInterface.queryReportTypeById(reportTypeId);
		Integer versionId = rType.getVersionId();
		Filter filter1 = new Filter();
		filter1.addRule(new FilterRule(FilterConstant.EQUAL, "id", versionId));
		cn.com.generaldata.os.newpojo.ReportVersion version = reportServiceInterface.getVersion(filter1, null);
		// 是否汇总
		Integer summarization = rType.getDataSummarization();
		// 报表汇总类别
		Integer dataType = rType.getDataType();
		// 取得指标汇总数据
		Map accounting = new HashMap();
		// 行式报表详情列表
		List<Row> rows = null;
		Stopwatch sw = Stopwatch.beginNano();
		// 用汇总
		if (summarization == Constants.YES) {
			// 指标汇总
			if (dataType.intValue() == ReportStyle.CELL.getValue()) {
				accounting = reportServiceInterface.getReportAccounting(user, rType, report.getReportMonth(),
						report.getQuarter());
			} else {
				List<Row> rowsAccounting = reportServiceInterface.getRowsAccounting(user, rType,
						report.getReportMonth(), report.getQuarter());

				Collection<Row> inputRows = Collections2.filter(report.getRows(), new Predicate<Row>() {
					@Override
					public boolean apply(Row row) {
						return row.getRowType() == Row.ROW_TYPE_INPUT;
					}
				});
				rows = Lists.newArrayList(rowsAccounting);
				rows.addAll(inputRows);
			}
		}
		sw.stop();
		logger.info("指标汇总耗时：" + sw);

		if (dataType.intValue() == ReportStyle.CELL.getValue()) {
			// 不同制度的指标对应关系
			sw = Stopwatch.beginNano();
			accounting = reportServiceInterface.getReportIndicator(user, rType, version.getStartDate(),
					report.getQuarter(), accounting);
			sw.stop();
			logger.info("指标关系耗时：" + sw);
			model.put("accounting", Json.toJson(accounting, JsonFormat.compact()));
		} else {
			report.setRows(rows);
		}
		model.put("reportTemplate", reportTemplateService.renderCreateTemplate(reportTypeId, report, user));
		model.put("report", report);

		model.put("user", user);
		model.put("reportType", rType);

		return new ModelAndView("/report-input.jsp", model);
	}

	/**
	 * 汇总本级涉海部门和下级单位的报表信息
	 * 
	 * @throws Exception
	 */
	public void generelReportsDetail(HttpServletRequest request, HttpServletResponse response, ReportVO reportVo)
			throws Exception {
		ReportType rType = reportServiceInterface.queryReportTypeById(reportVo.getReportTypeId());

		List<String> reportIds = reportServiceInterface.generelReportsDetail(reportVo.getUnitId(), rType,
				reportVo.getTimeDate(), reportVo.getQuarterDate());
		StringBuilder sb = new StringBuilder();
		for (String reportId : reportIds) {
			cn.com.generaldata.os.pojo.mvc.Report report = new cn.com.generaldata.os.pojo.mvc.Report();
			report = reportServiceInterface.queryMVCReportById(reportId);
			User user = userServiceInterface.queryUserById(report.getReportUserId());

			report = ReportServletHandler.generateReportForShow(report, user);
			String reportTypeId = report.getReportTypeId();
			String reportTemplate = reportTemplateService.renderDetailTemplate1(reportTypeId, report, user);
			sb.append(reportTemplate);
		}

		response.setContentType("text/html");
		response.getWriter().print(sb.toString());
		response.getWriter().flush();
	}

	/**
	 * 显示报表详情（只能看）
	 * 
	 * @param request
	 * @param response
	 * @return
	 * @throws ServletException
	 * @throws IOException
	 */
	@SuppressWarnings("unchecked")
	public ModelAndView showReportInfo(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		Map model = new HashMap();
		// 取得操作用户ID
		String userId = request.getParameter("reportOperatorId");
		// 取得报表ID
		String reportId = request.getParameter("reportId");

		// user
		User operatorUser = new User();
		cn.com.generaldata.os.pojo.mvc.Report report = new cn.com.generaldata.os.pojo.mvc.Report();

		if (userId == null) {
			return new ModelAndView("/error.jsp", null);
		}
		if (reportId == null) {
			return new ModelAndView("/error.jsp", null);
		}

		operatorUser = userServiceInterface.queryUserById(userId);
		report = reportServiceInterface.queryMVCReportById(reportId);
		User user = userServiceInterface.queryUserById(report.getReportUserId());

		report = ReportServletHandler.generateReportForShow(report, operatorUser);
		String reportTypeId = report.getReportTypeId();
		ReportType rType = reportServiceInterface.queryReportTypeById(reportTypeId);
		String reportTemplate = reportTemplateService
				.renderUpdateTemplate(reportTypeId, report.getRows(), report, user);
		model.put("reportTemplate", reportTemplate);
		model.put("report", report);
		model.put("user", user);
		model.put("reportType", rType);
		return new ModelAndView("/report-info.jsp", model);
	}

	@Data
	class PrintReport {
		private String userId;
		private String reportId;
	}

	@SuppressWarnings("unchecked")
	public ModelAndView showPrintSetting(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		String userId = request.getParameter("reportOperatorId");
		// 取得报表ID
		String reportId = request.getParameter("reportId");
		Map model = new HashMap();
		List<String> reportIds = Json.fromJsonAsList(String.class, reportId);
		Map result = new HashMap();
		model.put("printReportIds", reportIds);
		model.put("userId", userId);
		String json = Json.toJson(model, JsonFormat.compact());
		result.put("result", json);
		System.out.println(result.get("result"));
		return new ModelAndView("/print-setting.jsp", result);
	}

	/**
	 * 显示报表详细
	 * 
	 * @param request
	 * @param response
	 * @return
	 * @throws ServletException
	 * @throws IOException
	 */
	@SuppressWarnings("unchecked")
	public ModelAndView showReportDetail(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		Map model = new HashMap();
		// 取得操作用户ID
		String userId = request.getParameter("reportOperatorId");
		// 取得报表ID
		String reportId = request.getParameter("reportId");

		// user
		User operatorUser = new User();
		cn.com.generaldata.os.pojo.mvc.Report report = new cn.com.generaldata.os.pojo.mvc.Report();

		if (userId == null) {
			return new ModelAndView("/error.jsp", null);
		}
		if (reportId == null) {
			return new ModelAndView("/error.jsp", null);
		}

		operatorUser = userServiceInterface.queryUserById(userId);
		report = reportServiceInterface.queryMVCReportById(reportId);
		User user = userServiceInterface.queryUserById(report.getReportUserId());
		List<User> parentUser = userServiceInterface.findParentUser(report.getUnitId());
		if (parentUser != null) {
			boolean flag = false;
			for (User users : parentUser) {
				if (report.getReportOperatorId().equals(users.getId())) {
					flag = true;
					break;
				}
			}
			// 如果是上级终审驳回，本级可以继续审批
			if (flag && String.valueOf(report.getCheckStatus()).equals("3")) {
				// 如果是本级的上报报表，不能审批
				if (!user.getUserUnit().getId().equals(operatorUser.getUserUnit().getId())) {
					report.setCheckStatus(Byte.valueOf("1"));
				} else {
					report.setCheckStatus(Byte.valueOf("0"));
				}
			}

		}
		report = ReportServletHandler.generateReportForShow(report, operatorUser);
		String reportTypeId = report.getReportTypeId();
		ReportType rType = reportServiceInterface.queryReportTypeById(reportTypeId);
		String reportTemplate = reportTemplateService
				.renderUpdateTemplate(reportTypeId, report.getRows(), report, user);
		Map lastTimeIndicatorMap = reportServiceInterface.getLasttimeReportByTimetype(user, rType,
				report.getReportMonth(), report.getReportQuarter());
		model.put("lastTimeIndicatorMap", Json.toJson(lastTimeIndicatorMap, JsonFormat.compact()));
		model.put("reportTemplate", reportTemplate);
		model.put("report", report);
		model.put("user", user);
		model.put("reportType", rType);
		return new ModelAndView("/report-detail.jsp", model);
	}

	/**
	 * 修改报表
	 * 
	 * @param request
	 * @param response
	 * @return
	 * @throws ServletException
	 * @throws IOException
	 */
	public ModelAndView showReportUpdate(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		Map model = new HashMap();
		// 取得操作用户ID
		String userId = request.getParameter("reportOperatorId");
		// 取得报表ID
		String reportId = request.getParameter("reportId");

		// 取得代填报表用户ID
		// String proxyId = request.getParameter("reportProxyId");

		// user
		User user = new User();
		cn.com.generaldata.os.pojo.mvc.Report report = new cn.com.generaldata.os.pojo.mvc.Report();

		// Error Flag
		if (userId == null) {
			return new ModelAndView("/error.jsp", null);
		}
		if (reportId == null) {
			return new ModelAndView("/error.jsp", null);
		}
		// 报表操作者
		user = userServiceInterface.queryUserById(userId);
		report = reportServiceInterface.queryMVCReportById(reportId);
		// 报表所属者
		User userReport = userServiceInterface.queryUserById(report.getReportUserId());
		report = ReportServletHandler.generateReportForUpdate(report, user);
		User userProxy = userServiceInterface.queryUserById(report.getReportProxyId());
		String reportTypeId = report.getReportTypeId();
		ReportType rType = reportServiceInterface.queryReportTypeById(reportTypeId);
		// 如果是本级的上报报表，不能审批，只能修改
		if (userReport.getUserUnit().getId().equals(user.getUserUnit().getId())
				|| userProxy.getUserUnit().getId().equals(user.getUserUnit().getId())) {
			report.setCheckStatus(Byte.valueOf("0"));
		}
		Map lastTimeIndicatorMap = reportServiceInterface.getLasttimeReportByTimetype(user, rType,
				report.getReportMonth(), report.getReportQuarter());
		String reportTemplate = reportTemplateService.renderUpdateTemplate(reportTypeId, report.getRows(), report,
				userReport);
		model.put("reportTemplate", reportTemplate);
		model.put("report", report);
		model.put("lastTimeIndicatorMap", Json.toJson(lastTimeIndicatorMap, JsonFormat.compact()));
		model.put("user", user);
		model.put("reportType", rType);

		return new ModelAndView("/report-input.jsp", model);
	}

	/**
	 * 审核通过
	 * 
	 * @param request
	 * @param response
	 * @return
	 * @throws ServletException
	 * @throws IOException
	 */
	public ModelAndView passReport(HttpServletRequest request, HttpServletResponse response) throws ServletException,
			IOException {
		Map model = new HashMap();
		Short checkStatus;
		// 取得操作用户ID
		String operatorId = request.getParameter("reportOperatorId");
		// 取得报表ID
		String reportId = request.getParameter("reportId");
		// 取得意见
		String checkComment = request.getParameter("checkComment");

		// 自Request中获取checkResult
		String checkResult = request.getParameter("checkResult");

		// 自加 ，备份一份记录到数据库留作查看用
		Report reportBak = reportServiceInterface.queryMVCReportById(reportId);
		User operator = userServiceInterface.queryUserById(operatorId);
		if (operator.getArea() == null) {
			checkStatus = ReportConstant.FLAG_PASSED; // 6; 总局审核通过
		} else {
			checkStatus = ReportConstant.FLAG_PROVINCE_PASSED_COMMITTED; // 5;
																			// 省审核通过企业上报并提交总局
		}

		try {
			reportServiceInterface.passReport(reportBak, operatorId, checkStatus, checkComment, checkResult);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			return new ModelAndView("/error.jsp", null);
		}
		reportBak.setReportReferenceId(reportId);
		// reportServiceInterface.createMVCReport(reportBak);
		return new ModelAndView("/success.jsp", model);
	}

	/**
	 * 保存审核意见
	 * 
	 * @param request
	 * @param response
	 * @return
	 * @throws ServletException
	 * @throws IOException
	 */
	public ModelAndView saveAudit(HttpServletRequest request, HttpServletResponse response) throws ServletException,
			IOException {
		Map model = new HashMap();
		Short checkStatus = null;

		// 取得用户Id
		String operatorId = request.getParameter("reportOperatorId");
		// 取得报表ID
		String reportId = request.getParameter("reportId");
		// 取得意见
		String checkComment = request.getParameter("checkComment");

		// 审核状态
		String commit = request.getParameter("commit");

		Report report = reportServiceInterface.queryMVCReportById(reportId);

		User operator = userServiceInterface.queryUserById(operatorId);

		// 判断是否为省局审核
		if (operator.getArea() == null) {// 国家局审核
											// checkStatus =
											// ReportConstant.FLAG_OCEAN_SAVE_AUDIT;
			if (checkComment.trim() == "") {
				checkStatus = ReportConstant.FLAG_PRE_PASSED; // 66; 总局审核待通过
			} else {
				checkStatus = ReportConstant.FLAG_PRE_REJECTED; // 77; 总局待驳回
			}
		} else {// 省局级审核
				// checkStatus = ReportConstant.FLAG_SAVE_AUDIT;
				// 根据是否有审核意见，将状态置为待提交或待驳回状态
				// if(checkComment.trim() == ""){
				// checkStatus =
				// ReportConstant.FLAG_PROVINCE_PRE_PASSED_COMMITTED; //55;
				// 省初审通过企业报表，待正式提交总局
			// }else{
			// checkStatus = ReportConstant.FLAG_PROVINCE_PRE_REJECTED; //33;
			// 省初审驳回企业上报，进入待驳回
			// }

			if (commit == "1" || commit.equals("1")) {
				checkStatus = ReportConstant.FLAG_PROVINCE_PASSED_COMMITTED; // 55;
																				// 省初审通过企业报表，待正式提交总局
				try {
					reportServiceInterface.saveAudit(report, operatorId, checkStatus, checkComment);
				} catch (Exception e) {
					// TODO Auto-generated catch block
					return new ModelAndView("/error.jsp", null);
				}
			} else if ((commit.equals("0")) && !checkComment.trim().equals("")) {
				checkStatus = ReportConstant.FLAG_PROVINCE_REJECTED; // 33;
																		// 省初审驳回企业上报，进入待驳回
				try {
					reportServiceInterface.saveAudit(report, operatorId, checkStatus, checkComment);
				} catch (Exception e) {
					// TODO Auto-generated catch block
					return new ModelAndView("/error.jsp", null);
				}
			}
		}

		// reportServiceInterface.saveAudit(reportId, operatorId, checkStatus,
		// checkComment);

		// 代填人参数
		// String proxyParam = report.getReportProxyId() == null ? "" :
		// "&reportProxyId=" + report.getReportProxyId() ;

		// String url =
		// "/reports/service.do?method=showReportDetail&reportOperatorId="
		// + report.getReportOperatorId() + proxyParam + "&reportId=" +
		// reportId;

		// return new ModelAndView(url, model);
		// 操作成功后，不再返回到详细页面
		return new ModelAndView("/success.jsp", model);

	}

	/**
	 * 审核驳回
	 * 
	 * @param request
	 * @param response
	 * @return
	 * @throws ServletException
	 * @throws IOException
	 */
	public ModelAndView rejectReport(HttpServletRequest request, HttpServletResponse response) throws ServletException,
			IOException {
		Map model = new HashMap();
		Short checkStatus;
		// 取得操作用户ID
		String operatorId = request.getParameter("reportOperatorId");
		// 取得报表ID
		String reportId = request.getParameter("reportId");

		// 取得意见
		String checkComment = request.getParameter("checkComment");

		// 自Request中获取checkResult
		String checkResult = request.getParameter("checkResult");

		User operator = userServiceInterface.queryUserById(operatorId);
		checkStatus = ReportConstant.FLAG_PROVINCE_REJECTED; // 3: 省驳回企业上报
		// 当省级驳回企业上报后，为3时无法进行统一的筛选，所以直接成为提交状态便于企业修改
		// checkStatus = ReportConstant.FLAG_UNCOMMITTED; //0: 企业未提交
		// 便于企业对驳回的报表进行区分
		if (!StringUtils.isNotBlank(checkComment)) {
			checkComment = "审核驳回报表";
		}
		// 自加 ，备份一份记录到数据库留作查看用
		Report reportBak = reportServiceInterface.queryMVCReportById(reportId);
		try {
			reportServiceInterface.rejectReport(reportBak, operatorId, checkStatus, checkComment, checkResult);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			return new ModelAndView("/error.jsp", null);
		}
		reportBak.setReportReferenceId(reportId);
		// reportServiceInterface.createMVCReport(reportBak);

		return new ModelAndView("/success.jsp", model);
	}

	/**
	 * 保存修改后的
	 * 
	 * @param request
	 * @param response
	 * @return
	 * @throws ServletException
	 * @throws IOException
	 *             @
	 */
	public ModelAndView saveReport(HttpServletRequest request, HttpServletResponse response) throws ServletException,
			IOException {
		// 获取session
		// HttpSession session = request.getSession();

		String reportId = "";
		String url = "";
		Report report = ReportServletHandler.handleReportRequest(request);
		Report reportBak = report;
		// Report reportBak =
		// reportServiceInterface.queryMVCReportById(reportId);
		// 新增
		if (null == report.getReportId() || report.getReportId().trim().length() == 0) {
			// 由于行业增加多行业的功能，这个用户本身自带的行业ID字段不在使用，所以这个判断不在需要
			// if(report.getReportUnitIndustry() == "") {
			// report.setCheckStatus(ReportConstant.FLAG_PROVINCE_PASSED_UNCOMMITTED);
			// //2:省审核通过企业上报未提交总局
			// } else {
			report.setCheckStatus(ReportConstant.FLAG_UNCOMMITTED); // 0:企业提交省区未审核
			// }
			Industry industry = industryServiceInterface.queryIndustryById(report.getReportUnitIndustryId());
			report.setReportUnitIndustry(industry == null ? "" : industry.getDustryName());

			reportId = reportServiceInterface.createMVCReport(report);

			// webservice调用开始
			// report.setReportId(reportId);
			// ModelSend mo = new ModelSend();
			// mo.setObj(report);
			// mo.setFlag("9");
			// new Thread(mo).start();
			// webservice调用结束
		} else {
			// if(report.getReportUnitIndustry() == "") {
			// report.setCheckStatus(ReportConstant.FLAG_PROVINCE_PASSED_UNCOMMITTED);
			// //2:省审核通过企业上报未提交总局
			// } else {
			// report.setCheckStatus(ReportConstant.FLAG_UNCOMMITTED);
			// //0:企业提交省区未审核
			// }
			report.setCheckStatus(ReportConstant.FLAG_UNCOMMITTED);
			report.setCheckComment("");
			reportServiceInterface.modifyMVCReport(report);
			reportId = report.getReportId();
			// 原本数据的ID号
			// reportBak.setReportReferenceId(reportId);
			// //自加，备份一份记录到数据库
			// String reportBakId =
			// reportServiceInterface.createMVCReport4Mark(reportBak);

			// if ((report.getCheckStatus() == ReportConstant.FLAG_COMMITTED)
			// || (report.getCheckStatus() ==
			// ReportConstant.FLAG_PROVINCE_PASSED_COMMITTED)) {
			// report.setCheckStatus(ReportConstant.FLAG_SAVE_AUDIT);
			// }
		}
		// 代填人参数
		String proxyParam = report.getReportProxyId() == null ? "" : "&reportProxyId=" + report.getReportProxyId();

		url = "/reports/service.do?method=showReportDetail&reportOperatorId=" + report.getReportOperatorId()
				+ proxyParam + "&reportId=" + reportId;
		if (request.getParameter("commit") != null) {
			if (request.getParameter("commit").equals("1") || request.getParameter("commit").equals("2")) {
				url = "/success.jsp";
			}
		}

		return new ModelAndView(url, null);
	}

	/**
	 * 提交报表
	 * 
	 * @param request
	 * @param response
	 * @return
	 * @throws ServletException
	 * @throws IOException
	 *             @
	 */
	public ModelAndView submitReport(HttpServletRequest request, HttpServletResponse response) throws ServletException,
			IOException {
		String reportId = "";
		String url = "";
		Report report = ReportServletHandler.handleReportRequest(request);

		// if(report.getReportUnitIndustry() == "") {
		// report.setCheckStatus(ReportConstant.FLAG_PROVINCE_PASSED_COMMITTED);
		// //5: 省审核通过企业上报并提交总局
		// } else {
		report.setCheckStatus(ReportConstant.FLAG_COMMITTED); // 1: 企业提交省区未审核
		report.setCheckComment("");
		// }
		Industry industry = industryServiceInterface.queryIndustryById(report.getReportUnitIndustryId());
		report.setReportUnitIndustry(industry == null ? "" : industry.getDustryName());

		reportId = reportServiceInterface.submitReport(report);

		// 代填人参数
		String proxyParam = report.getReportProxyId() == null ? "" : "&reportProxyId=" + report.getReportProxyId();

		url = "/reports/service.do?method=showReportDetail&reportOperatorId=" + report.getReportOperatorId()
				+ proxyParam + "&reportId=" + reportId;
		if (request.getParameter("commit") != null) {
			if (request.getParameter("commit").equals("1") || request.getParameter("commit").equals("2")) {
				url = "/success.jsp";
			}
		}

		return new ModelAndView(url, null);
	}

	/**
	 * 验证报表规则
	 * 
	 * @param request
	 * @param response
	 * @return
	 * @throws IOException
	 */
	public ModelAndView checkReport(HttpServletRequest request, HttpServletResponse response) throws IOException {
		String rules = request.getParameter("rules");
		String reportId = request.getParameter("reportId");
		// JSONObject json = new JSONObject();
		// json.put("checkResult", ReportCheckHandler.checkReport(reportId,
		// rules));
		response.setCharacterEncoding("UTF-8");
		String json = String.format("{\"checkResult\":\"%s\"}", ReportCheckHandler.checkReport(reportId, rules));
		response.getWriter().print(json);
		return null;
	}

	/**
	 * 制度报表汇总
	 * 
	 * @param request
	 * @param response
	 * @param command
	 * @throws Exception
	 */
	public ModelAndView reportStat(HttpServletRequest request, HttpServletResponse response, ReportStatVO command)
			throws Exception {
		ModelAndView mav = new ModelAndView("/report-stat.jsp");

		ReportStatResult statResult = reportStatService.stat(command);
		mav.addObject("statResult", statResult);
		mav.addObject("reportStatVO", Json.toJson(command, JsonFormat.compact()));
		Object reportType = indicatorSystemDao.fetch(
				cn.com.generaldata.jsme_indicator_system.entity.ReportTypeNz.class, command.getReportTypeId());
		mav.addObject("reportType", Json.toJson(reportType, JsonFormat.compact()));
		return mav;
	}

	/***
	 * 制度汇总来源
	 */
	public void reportStatSource(HttpServletRequest request, HttpServletResponse response, ReportStatVO command)
			throws Exception {
		response.setHeader("Cache-Control", "no-cache");
		response.setContentType("text/plain");
		PrintWriter pw = response.getWriter();
		// pw.write(Json.toJson(reportStatService.statSource(command)));
		response.flushBuffer();

	}

	public void setUserServiceInterface(UserService userServiceInterface) {
		this.userServiceInterface = userServiceInterface;
	}

	public void setReportServiceInterface(ReportServiceInterface reportServiceInterface) {
		this.reportServiceInterface = reportServiceInterface;
	}

	public void setRoleServiceInterface(RoleService roleServiceInterface) {
		this.roleServiceInterface = roleServiceInterface;
	}

	public void setIndustryServiceInterface(IndustryService industryServiceInterface) {
		this.industryServiceInterface = industryServiceInterface;
	}

	public void setReportTemplateService(ReportTemplateService reportTemplateService) {
		this.reportTemplateService = reportTemplateService;
	}

	public void setReportStatService(ReportStatService reportStatService) {
		this.reportStatService = reportStatService;
	}

	public void setIndicatorSystemDao(Dao indicatorSystemDao) {
		this.indicatorSystemDao = indicatorSystemDao;
	}

	public void setTimeLimit(boolean timeLimit) {
		this.timeLimit = timeLimit;
	}

	/**
	 * 下载报表模板
	 * @param request
	 * @param response
	 * @param command
	 * @throws Exception
	 */
	public void downTemples(HttpServletRequest request, HttpServletResponse response, IndicatorStatQueryVO command)
			throws Exception {
		Properties properties = new Properties();
		java.io.InputStream inputstream = getClass().getResourceAsStream("/fileupload.properties");
		try {
			properties.load(inputstream);
		} catch (Exception ex) {
			logger.error("加载配置文件出错", ex);
		}
		//企业ID
		String countyId = command.getCountyId();
		String path = reportServiceInterface.buildExcel(countyId);
		if (path != null) {
			File file = new File(properties.getProperty("excelTemplePath").trim() + path); // 路径是存文件的路径

			String encodedfileName = new String(path.getBytes(), "ISO8859-1");
			response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + encodedfileName + "\"");
			OutputStream out = response.getOutputStream();
			FileInputStream fin = new FileInputStream(file);
			byte data[] = new byte[1024];
			int len;
			try {
				while ((len = fin.read(data)) > -1) {
					out.write(data);
				}
				fin.close();
				out.close();
				out.flush();
			} finally {
				Streams.safeClose(out);
				file.delete();
			}
		}
	}
}
